﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Interfaces.Enums;
using Interfaces.Models;
using Interfaces.Repositories;
using Interfaces.RepositoryModels.InternalModels.UserRoleModels;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SQLRepositories;
using SQLRepositories.UserRoleRepositories;

namespace DataProviderIntegrationTests.RepositoryTests
{
    [TestClass]
    public class UserRepositoryTests
    {
        readonly IRepository<UserModel> _repository = new UserRepository(new DBEconomicInformationServiceContext());
        
        private UserModel CreateNewUser(Guid userId, Guid roleId)
        {
            var mockUser = new UserModel();
            var mockRole = new RoleModel
                {
                    Id = roleId, 
                    Type = RoleType.User,
                    CreatedDate = DateTime.Now,
                    ChangedDate = DateTime.Now,
                    Users = new List<UserModel>
                        {
                            mockUser
                        }
                };

            
            mockUser.Email="Test@test";
            mockUser.Id = userId;
            mockUser.Password = "passw";
            mockUser.UserName = "Test";
            mockUser.Roles = new List<RoleModel> {mockRole};
            mockUser.CreatedDate = DateTime.Now;
            mockUser.ChangedDate = DateTime.Now;
            _repository.Create(mockUser);
            return mockUser;
        }

        [TestMethod]
        public void CreateUserEntity_IntegrationTest()
        {
            var userId = Guid.NewGuid();
            var roleId = Guid.NewGuid();
            CreateNewUser(userId, roleId);
            var createdUser = _repository.GetById(userId);
            Assert.IsNotNull(createdUser);
            Assert.AreEqual(createdUser.Id, userId);
            Assert.IsNotNull(createdUser.Roles);
        }

        [TestMethod]
        public void DeleteUserEntity_IntegrationTest()
        {
            var userId = Guid.NewGuid();
            var roleId = Guid.NewGuid();
            CreateNewUser(userId, roleId);
            _repository.Delete(userId);
            var deletedUser = _repository.GetById(userId);
            Assert.IsNull(deletedUser);
        }

        [TestMethod]
        public void UpdateUserEntity_IntegarationTest()
        {
            const string updateEmailText = "TestUpdate@test";
            const string updateNameText = "TestUpadte";
            
            var userId = Guid.NewGuid();
            var roleUserId = Guid.NewGuid();
            var roleAdminId = Guid.NewGuid();

            var newUser = CreateNewUser(userId, roleUserId);

            var mockUser = new UserModel();
            var mockRoleAdmin = new RoleModel
                {
                    Id = roleAdminId,
                    Type = RoleType.Admin,
                    Users = new List<UserModel>{newUser}
                };

            newUser.Email = updateEmailText;
            newUser.UserName = updateNameText;
            newUser.Roles.Add(mockRoleAdmin);

            _repository.Update(mockUser);

            var updatedUser = _repository.GetById(userId);

            Assert.IsNotNull(updatedUser);
            Assert.IsNotNull(updatedUser.Roles);
            Assert.AreEqual(2, updatedUser.Roles.Count);
            Assert.AreEqual(updateEmailText,updatedUser.Email);
            Assert.AreEqual(updateNameText,updatedUser.UserName);
            Assert.AreEqual(userId,updatedUser.Id);
        }

        [TestMethod]
        public void UpdateUserEntityTwoUsers_IntegrationTest()
        {
            const string updateEmailText = "TestUpdate@test";
            const string updateNameText = "TestUpadte";

            var userId = Guid.NewGuid();
            var adminId = Guid.NewGuid();
            var roleUserId = Guid.NewGuid();
            var roleAdminId = Guid.NewGuid();

            var user = CreateNewUser(userId, roleUserId);
            var admin = CreateNewUser(adminId, roleAdminId);
            
            user.Email = updateEmailText;
            user.UserName = updateNameText;
            user.Roles.Add(admin.Roles.FirstOrDefault());

            admin.Email = updateEmailText;
            admin.UserName = updateNameText;
            admin.Roles.Add(user.Roles.FirstOrDefault());
         
            _repository.Update(user);

            var updatedUser = _repository.GetById(userId);

            Assert.IsNotNull(updatedUser);
            Assert.IsNotNull(updatedUser.Roles);
            Assert.AreEqual(2, updatedUser.Roles.Count);
            Assert.AreEqual(updateEmailText, updatedUser.Email);
            Assert.AreEqual(updateNameText, updatedUser.UserName);
            Assert.AreEqual(userId, updatedUser.Id);

            var secondupdatedUser = _repository.GetById(adminId);

            Assert.IsNotNull(secondupdatedUser);
            Assert.IsNotNull(secondupdatedUser.Roles);
            Assert.AreEqual(2, secondupdatedUser.Roles.Count);
            Assert.AreEqual(updateEmailText, secondupdatedUser.Email);
            Assert.AreEqual(updateNameText, secondupdatedUser.UserName);
            Assert.AreEqual(adminId, secondupdatedUser.Id);

        }
    }
}
